package com.qf.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.qf.mapper.AccountMapper;
import com.qf.pojo.Account;
import com.qf.service.AccountService;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;

@Service
public class AccountServiceImpl2 implements AccountService/*, ApplicationContextAware */{

    //循环依赖 -- spring有三级缓存
//    @Autowired
//    private AccountService accountService;

    @Autowired
    private ApplicationContext ioc;

   /* @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.ioc = applicationContext;
    }*/


    @Autowired
    private AccountMapper accountMapper;

    @Override
    public List<Account> findAll() {
        return accountMapper.findAll();
    }

    @Override
    public PageInfo<Account> findPage(int pageNum, int size) {
        PageHelper.startPage(pageNum,size);

        List<Account> accounts = accountMapper.findAll();

        return new PageInfo<>(accounts);
    }

    @Override
    @Transactional
    public void go(Double money, String inName, String outName) throws ParseException, InterruptedException {
        //转账
        ioc.getBean(AccountService.class).transfer(money,inName,outName);

        //保存转账记录
        ioc.getBean(AccountService.class).saveLog();
    }

    @Override
    @Transactional
    public void saveLog() {
        int i = 1/0;
    }

    /**
        propagation:事务的传播行为   A方法中嵌套调用B方法，给B方法设置事务传播行为
             ***REQUIRED(默认值)： B方法要求事务的，如果A方法存在事务，B方法和A方法用同一个事务；如果A方法没有事务，那么B方法会创建事务
             SUPPORTS： B方法支持事务，如果A有，B方法和A共用一个；如果A没有，B也没有
             MANDATORY： B方法要求A方法必须要带事务，如果A方法有事务，B和A共用一个事务；如果A方法没带事务，直接报错
             ***REQUIRES_NEW：B方法不管A方法是否有事务，都会自动创建一个新的事务
                转账业务：
                    转账
                    转账记录 -- 转账记录的业务是否应该影响转账业务的执行结果？？？
             NOT_SUPPORTED：B方法不支持事务，不管A有没有事务，B方法都没有事务
             NEVER： B方法要求A方法必须不带事务，如果A带了事务，就报错
             NESTED：回滚点（不用）

     */
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
    public int transfer(Double money, String inName, String outName) throws InterruptedException, ParseException {
        //转出
        accountMapper.updateMoneyByName(outName,-money);

        //转入
        accountMapper.updateMoneyByName(inName,money);

        return 1;
    }
}
